"""
日志工具
"""

import logging
import sys
from pathlib import Path
from typing import Optional

import structlog
from structlog.stdlib import LoggerFactory

from config import settings


def setup_logging() -> None:
    """设置日志配置"""
    # 确保日志目录存在
    log_dir = Path(settings.log_dir)
    log_dir.mkdir(parents=True, exist_ok=True)

    # 配置标准库logging
    logging.basicConfig(
        format="%(message)s",
        stream=sys.stdout,
        level=getattr(logging, settings.log_level.upper()),
    )

    # 配置structlog
    structlog.configure(
        processors=[
            structlog.stdlib.filter_by_level,
            structlog.stdlib.add_logger_name,
            structlog.stdlib.add_log_level,
            structlog.stdlib.PositionalArgumentsFormatter(),
            structlog.processors.TimeStamper(fmt="iso"),
            structlog.processors.StackInfoRenderer(),
            structlog.processors.format_exc_info,
            structlog.processors.UnicodeDecoder(),
            structlog.processors.JSONRenderer() if not settings.debug else structlog.dev.ConsoleRenderer(),
        ],
        context_class=dict,
        logger_factory=LoggerFactory(),
        wrapper_class=structlog.stdlib.BoundLogger,
        cache_logger_on_first_use=True,
    )

    # 设置第三方库日志级别
    logging.getLogger("uvicorn").setLevel(logging.INFO)
    logging.getLogger("uvicorn.access").setLevel(logging.INFO)
    logging.getLogger("sqlalchemy.engine").setLevel(
        logging.INFO if settings.database_echo else logging.WARNING
    )


def get_logger(name: Optional[str] = None) -> structlog.stdlib.BoundLogger:
    """获取logger实例"""
    return structlog.get_logger(name)


def log_execution_details(
    logger: structlog.stdlib.BoundLogger,
    execution_id: int,
    task_id: int,
    step: str,
    message: str,
    level: str = "info",
    **kwargs
) -> None:
    """记录执行详情"""
    log_method = getattr(logger, level.lower(), logger.info)
    log_method(
        message,
        execution_id=execution_id,
        task_id=task_id,
        step=step,
        **kwargs
    )


def log_git_operation(
    logger: structlog.stdlib.BoundLogger,
    operation: str,
    repo_url: str,
    branch: Optional[str] = None,
    commit_id: Optional[str] = None,
    success: bool = True,
    error: Optional[str] = None,
    **kwargs
) -> None:
    """记录Git操作"""
    log_data = {
        "operation": operation,
        "repo_url": repo_url,
        "success": success,
    }

    if branch:
        log_data["branch"] = branch
    if commit_id:
        log_data["commit_id"] = commit_id
    if error:
        log_data["error"] = error

    log_data.update(kwargs)

    if success:
        logger.info("Git操作成功", **log_data)
    else:
        logger.error("Git操作失败", **log_data)


def log_api_request(
    logger: structlog.stdlib.BoundLogger,
    method: str,
    path: str,
    user_id: Optional[str] = None,
    ip_address: Optional[str] = None,
    **kwargs
) -> None:
    """记录API请求"""
    log_data = {
        "method": method,
        "path": path,
    }

    if user_id:
        log_data["user_id"] = user_id
    if ip_address:
        log_data["ip_address"] = ip_address

    log_data.update(kwargs)

    logger.info("API请求", **log_data)


def log_task_execution(
    logger: structlog.stdlib.BoundLogger,
    task_id: int,
    execution_id: int,
    status: str,
    duration: Optional[int] = None,
    error: Optional[str] = None,
    **kwargs
) -> None:
    """记录任务执行"""
    log_data = {
        "task_id": task_id,
        "execution_id": execution_id,
        "status": status,
    }

    if duration is not None:
        log_data["duration_seconds"] = duration
    if error:
        log_data["error"] = error

    log_data.update(kwargs)

    if status == "success":
        logger.info("任务执行成功", **log_data)
    elif status == "failure":
        logger.error("任务执行失败", **log_data)
    else:
        logger.info("任务执行状态更新", **log_data)


# 初始化日志设置
setup_logging()